﻿using System;
using System.Linq;
using System.IO;
using System.IO.IsolatedStorage;
using System.Collections.Generic;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Framework.Client;
using Microsoft.LightSwitch.Presentation;
using Microsoft.LightSwitch.Presentation.Extensions;
using System.Windows.Controls;
using System.Net;
using System.Text;
using System.Threading;
using System.Security.Cryptography;
namespace LightSwitchApplication
{
    public partial class PrescriptionsFillableListDetail
    {
        private string xml;
        public static ManualResetEvent allDone = new ManualResetEvent(false);

        partial void PrescriptionsFillableListDetail_InitializeDataWorkspace(List<IDataService> saveChangesTo)
        {
            // Write your code here.

            this.Cart = null;
            this.ErrMsg = "N/A";
        }

        partial void PrescriptionsFillableListDetail_Created()
        {
            // Write your code here.
            this.FindControl("NewPrescription").ControlAvailable += (sender, args) =>
            {
                ChildWindow dialog = args.Control as ChildWindow;
                dialog.Closed += (s, a) =>
                {
                    if (!dialog.DialogResult.HasValue || dialog.DialogResult == false)
                        if (this.PrescriptionsFillable.SelectedItem != null)
                            this.PrescriptionsFillable.SelectedItem.Delete();
                };
            };

            
            this.FindControl("NewSellOrder").ControlAvailable += (sender, args) =>
            {
                ChildWindow dialog = args.Control as ChildWindow;
                dialog.Closed += (s, a) =>
                {
                    if (!dialog.DialogResult.HasValue || dialog.DialogResult == false)
                        if(this.SellOrders.SelectedItem != null)
                            this.SellOrders.SelectedItem.Delete();
                };
            };
        }

        partial void FillPrescription_CanExecute(ref bool result)
        {
            // Write your code here  
            ErrMsg = "N/A";
            Prescription prescription = this.PrescriptionsFillable.SelectedItem;
            if (prescription != null)
            {
                var drugsAvailable = this.DataWorkspace.ApplicationData.DrugsForPrescription(prescription.MedicalName, prescription.Dosage,
                    prescription.TakingTimesPerDay, prescription.TakingDaysPerWeek, prescription.TakingWeeks, prescription.Customer.DOB, prescription.Physician.IsAssistant, prescription.Unit).OrderBy(d => d.LegalAge);
                if (drugsAvailable.FirstOrDefault() == null)
                    ErrMsg = "No available drugs";
                else
                {
                    DateTime now = DateTime.Today;
                    int age = now.Year - prescription.Customer.DOB.Year;
                    if (prescription.Customer.DOB > now.AddYears(-age)) age--;
                    var drugs = drugsAvailable.Where(d => d.LegalAge == null || d.LegalAge <= age);
                    Drug drug = drugs.FirstOrDefault();
                    if (drug == null)
                    {
                        ErrMsg = "The patient should be at least " + drug.LegalAge + " years old to take " + drug.Tag;
                    }

                    if (prescription.Physician.IsAssistant && drugs.Where(d => d.Type != "R").FirstOrDefault() == null)
                    {
                        ErrMsg = "There is no non-restricted prescription drugs to fill the prescription. ";
                    }
                }
                this.LeftFillTimes = prescription.Refills + 1 - prescription.SellOrders.Count();
                result = ErrMsg == "N/A" && !this.SellOrders.Any(so => so.Prescription == this.PrescriptionsFillable.SelectedItem);
            }
        }

        partial void FillPrescription_Execute()
        {
            // Write your code here.
            if (this.Cart == null)
            {
                this.Cart = new SellOrderHeader();
                this.Cart.CreatedTime = DateTime.Now;
            }
            NewSellOrder = this.Cart.SellOrders.AddNew();
            NewSellOrder.Prescription = this.PrescriptionsFillable.SelectedItem;
            var drugs = this.DrugsForPrescription.Where(d => d.CommercialName == this.PrescriptionsFillable.SelectedItem.CommercialName);
            if (drugs.Any())
                NewSellOrder.Drug = drugs.FirstOrDefault();
            else
                NewSellOrder.Drug = this.DrugsForPrescription.FirstOrDefault();
            this.OpenModalWindow("NewSellOrder");
        }

        partial void PrescriptionListDeleteSelected_CanExecute(ref bool result)
        {
            // Write your code here.
            /*result = this.PrescriptionsFillable.SelectedItem != null &&
                this.PrescriptionsFillable.SelectedItem.Id == 0;*/
        }

        partial void PrescriptionListDeleteSelected_Execute()
        {
            // Write your code here.
            this.PrescriptionsFillable.SelectedItem.Delete();
        }

        partial void PrescriptionListAddAndEditNew_CanExecute(ref bool result)
        {
            // Write your code here.

        }

        partial void PrescriptionListAddAndEditNew_Execute()
        {
            // Write your code here.
            NewPrescription = this.PrescriptionsFillable.AddNew();
            NewPrescription.Customer = this.DataWorkspace.ApplicationData.Customers_Single(this.PrescriptionPatientId);
            NewPrescription.Dosage = 1;
            NewPrescription.TakingTimesPerDay = 1;
            NewPrescription.TakingDaysPerWeek = 1;
            NewPrescription.TakingWeeks = 1;
            NewPrescription.Refills = 0;
            this.OpenModalWindow("NewPrescription");            
        }

        partial void ConfirmNewPrescription_Execute()
        {
            // Write your code here.
            this.CloseModalWindow("NewPrescription");

        }

        partial void CancelNewPrescription_Execute()
        {
            // Write your code here.
            this.CloseModalWindow("NewPrescription");
            this.PrescriptionsFillable.SelectedItem.Delete();
        }

        partial void CancelPrescription_CanExecute(ref bool result)
        {
            // Write your code here.
            result = this.PrescriptionsFillable.SelectedItem != null &&
                this.PrescriptionsFillable.SelectedItem.ErrMsg == null &&
                this.ErrMsg != "N/A";
        }

        partial void CancelPrescription_Execute()
        {
            // Write your code here.
            this.PrescriptionsFillable.SelectedItem.ErrMsg = DateTime.Today.ToShortDateString() + " : " + this.ErrMsg;
        }

        partial void PlaceOrder_CanExecute(ref bool result)
        {
            // Write your code here.
            result = this.CanSave && this.Cart != null && this.Cart.SellOrders.Any();
        }

        partial void PlaceOrder_Execute()
        {
            SellOrder first = this.SellOrders.First();

            xml = "<claim " +
                  "queryFlag=\"1\" " +
                  "externalID=\"" + first.Id + "\" " +
                  "subscriberID=\"" + first.Prescription.Customer.SubscriberId + "\">";
            // Get the information for the prescriptions to be sent.
            foreach (var sellOrder in this.SellOrders)
            {
                Prescription pres = sellOrder.Prescription;

                int externalID = sellOrder.Id;
                string subscriberID = sellOrder.Prescription.Customer.SubscriberId;
                decimal amountBilled = sellOrder.SubTotal;
                DateTime serviceDate = sellOrder.SellOrderHeader.CreatedTime;

                string prescriberName = string.Empty;
                if (pres.Physician.IsAssistant)
                    prescriberName = "medicalStaffName=\"" + pres.Physician.FirstName + " " + pres.Physician.LastName + "\" ";
                else
                    prescriberName = "physicianName=\"" + pres.Physician.FirstName + " " + pres.Physician.LastName + "\" ";

                string drugCode = sellOrder.Drug.DrugCode;

                //Fill in the attributes for the XML to be posted
                //queryFlag should be set to 0 later
                xml +=
                       "<transaction " +
                       "externalID=\"" + externalID + "\" " +
                       "amountBilled=\"" + amountBilled + "\" " +
                       "serviceDate=\"" + serviceDate + "\" " +
                       prescriberName +
                       "drugCode=\"" + drugCode + "\" />";
            }

            xml += "</claim>";

            //Compute the signature for the POST with SHA1s
            string signature = GetSHA1Hash(GetSHA1Hash(xml) + "654Pharmacy Group Key321");

            //Add the request and client tags to the XML
            xml = "<request><client id=\"101\" signature=\"" + signature + "\"/>" + xml;
            xml = xml + "</request>";

            WebRequest req = null;
            string uri = "http://cs744.dyndns.org/services/submitClaim.php";
            req = WebRequest.Create(uri);
            req.Method = "POST";
            req.ContentType = "text/xml";
            req.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), req);

            this.IsFinished = true;
            this.Save();
            this.Close(false);
        }

        private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

            // End the operation
            Stream postStream = request.EndGetRequestStream(asynchronousResult);

            // Convert the string into a byte array.
            byte[] byteArray = Encoding.UTF8.GetBytes(xml);

            // Write to the request stream.
            postStream.Write(byteArray, 0, xml.Length);
            postStream.Close();

            // Start the asynchronous operation to get the response
            request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
        }

        private void GetResponseCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;

            // End the operation
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
            Stream streamResponse = response.GetResponseStream();
            StreamReader streamRead = new StreamReader(streamResponse);
            string responseString = streamRead.ReadToEnd();
            if (responseString != null)
            {
                Console.WriteLine(responseString);
            }
            // Close the stream object
            streamResponse.Close();
            streamRead.Close();

            // Release the HttpWebResponse
            response.Close();
            allDone.Set();
        }

        private string GetSHA1Hash(string str)
        {
            SHA1 sha = new SHA1Managed();

            byte[] result = sha.ComputeHash(Encoding.UTF8.GetBytes(str));

            StringBuilder sBuilder = new StringBuilder();

            for (int i = 0; i < result.Length; i++)
            {
                sBuilder.Append(result[i].ToString("x2"));
            }

            return sBuilder.ToString();
        }

        partial void PrescriptionsFillableListDetail_Saving(ref bool handled)
        {
            // Write your code here.
            if (!IsFinished && this.Cart != null)
            {
                foreach (SellOrder so in this.Cart.SellOrders)
                    so.Delete();
                this.Cart.Delete();
            }                
            handled = false;
        }

        partial void ConfirmNewSellOrder_Execute()
        {
            // Write your code here.
            this.CloseModalWindow("NewSellOrder");

        }

        partial void CancelNewSellOrder_Execute()
        {
            // Write your code here.
            this.CloseModalWindow("NewSellOrder");
            NewSellOrder.Delete();
        }   

                
        

        
    }
}
